home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-I386 / STRING-4.{18 < prev    next >
Text File  |  1999-09-17  |  14KB  |  697 lines

  1. #ifndef _I386_STRING_I486_H_
  2. #define _I386_STRING_I486_H_
  3.  
  4. /*
  5.  * This string-include defines all string functions as inline
  6.  * functions. Use gcc. It also assumes ds=es=data space, this should be
  7.  * normal. Most of the string-functions are rather heavily hand-optimized,
  8.  * see especially strtok,strstr,str[c]spn. They should work, but are not
  9.  * very easy to understand. Everything is done entirely within the register
  10.  * set, making the functions fast and clean. 
  11.  *
  12.  *        Copyright (C) 1991, 1992 Linus Torvalds
  13.  *        Revised and optimized for i486/pentium
  14.  *        1994/03/15 by Alberto Vignani/Davide Parodi @crf.it
  15.  *
  16.  *    Split into 2 CPU specific files by Alan Cox to keep #ifdef noise down.
  17.  */
  18.  
  19. #define __HAVE_ARCH_STRCPY
  20. extern inline char * strcpy(char * dest,const char *src)
  21. {
  22. register char *tmp= (char *)dest;
  23. register char dummy;
  24. __asm__ __volatile__(
  25.     "\n1:\t"
  26.     "movb (%0),%2\n\t"
  27.     "incl %0\n\t"
  28.     "movb %2,(%1)\n\t"
  29.     "incl %1\n\t"
  30.     "testb %2,%2\n\t"
  31.     "jne 1b"
  32.     :"=r" (src), "=r" (tmp), "=q" (dummy)
  33.     :"0" (src), "1" (tmp)
  34.     :"memory");
  35. return dest;
  36. }
  37.  
  38. #define __HAVE_ARCH_STRNCPY
  39. extern inline char * strncpy(char * dest,const char *src,size_t count)
  40. {
  41. register char *tmp= (char *)dest;
  42. register char dummy;
  43. if (count) {
  44. __asm__ __volatile__(
  45.     "\n1:\t"
  46.     "movb (%0),%2\n\t"
  47.     "incl %0\n\t"
  48.     "movb %2,(%1)\n\t"
  49.     "incl %1\n\t"
  50.     "decl %3\n\t"
  51.     "je 3f\n\t"
  52.     "testb %2,%2\n\t"
  53.     "jne 1b\n\t"
  54.     "2:\tmovb %2,(%1)\n\t"
  55.     "incl %1\n\t"
  56.     "decl %3\n\t"
  57.     "jne 2b\n\t"
  58.     "3:"
  59.     :"=r" (src), "=r" (tmp), "=q" (dummy), "=r" (count)
  60.     :"0" (src), "1" (tmp), "3" (count)
  61.     :"memory");
  62.     } /* if (count) */
  63. return dest;
  64. }
  65.  
  66. #define __HAVE_ARCH_STRCAT
  67. extern inline char * strcat(char * dest,const char * src)
  68. {
  69. register char *tmp = (char *)(dest-1);
  70. register char dummy;
  71. __asm__ __volatile__(
  72.     "\n1:\tincl %1\n\t"
  73.     "cmpb $0,(%1)\n\t"
  74.     "jne 1b\n"
  75.     "2:\tmovb (%2),%b0\n\t"
  76.     "incl %2\n\t"
  77.     "movb %b0,(%1)\n\t"
  78.     "incl %1\n\t"
  79.     "testb %b0,%b0\n\t"
  80.     "jne 2b\n"
  81.     :"=q" (dummy), "=r" (tmp), "=r" (src)
  82.     :"1"  (tmp), "2"  (src)
  83.     :"memory");
  84. return dest;
  85. }
  86.  
  87. #define __HAVE_ARCH_STRNCAT
  88. extern inline char * strncat(char * dest,const char * src,size_t count)
  89. {
  90. register char *tmp = (char *)(dest-1);
  91. register char dummy;
  92. __asm__ __volatile__(
  93.     "\n1:\tincl %1\n\t"
  94.     "cmpb $0,(%1)\n\t"
  95.     "jne 1b\n"
  96.     "2:\tdecl %3\n\t"
  97.     "js 3f\n\t"
  98.     "movb (%2),%b0\n\t"
  99.     "incl %2\n\t"
  100.     "movb %b0,(%1)\n\t"
  101.     "incl %1\n\t"
  102.     "testb %b0,%b0\n\t"
  103.     "jne 2b\n"
  104.     "3:\txorl %0,%0\n\t"
  105.     "movb %b0,(%1)\n\t"
  106.     :"=q" (dummy), "=r" (tmp), "=r" (src), "=r" (count)
  107.     :"1"  (tmp), "2"  (src), "3"  (count)
  108.     :"memory");
  109. return dest;
  110. }
  111.  
  112. #define __HAVE_ARCH_STRCMP
  113. extern inline int strcmp(const char * cs,const char * ct)
  114. {
  115. register int __res;
  116. __asm__ __volatile__(
  117.     "\n1:\tmovb (%1),%b0\n\t"
  118.     "incl %1\n\t"
  119.     "cmpb %b0,(%2)\n\t"
  120.     "jne 2f\n\t"
  121.     "incl %2\n\t"
  122.     "testb %b0,%b0\n\t"
  123.     "jne 1b\n\t"
  124.     "xorl %0,%0\n\t"
  125.     "jmp 3f\n"
  126.     "2:\tmovl $1,%0\n\t"
  127.     "jb 3f\n\t"
  128.     "negl %0\n"
  129.     "3:"
  130.     :"=q" (__res), "=r" (cs), "=r" (ct)
  131.     :"1" (cs), "2" (ct)
  132.     : "memory" );
  133. return __res;
  134. }
  135.  
  136. #define __HAVE_ARCH_STRNCMP
  137. extern inline int strncmp(const char * cs,const char * ct,size_t count)
  138. {
  139. register int __res;
  140. __asm__ __volatile__(
  141.     "\n1:\tdecl %3\n\t"
  142.     "js 2f\n\t"
  143.     "movb (%1),%b0\n\t"
  144.     "incl %1\n\t"
  145.     "cmpb %b0,(%2)\n\t"
  146.     "jne 3f\n\t"
  147.     "incl %2\n\t"
  148.     "testb %b0,%b0\n\t"
  149.     "jne 1b\n"
  150.     "2:\txorl %0,%0\n\t"
  151.     "jmp 4f\n"
  152.     "3:\tmovl $1,%0\n\t"
  153.     "jb 4f\n\t"
  154.     "negl %0\n"
  155.     "4:"
  156.     :"=q" (__res), "=r" (cs), "=r" (ct), "=r" (count)
  157.     :"1"  (cs), "2"  (ct),  "3" (count));
  158. return __res;
  159. }
  160.  
  161. #define __HAVE_ARCH_STRCHR
  162. extern inline char * strchr(const char * s, int c)
  163. {
  164. register char * __res;
  165. __asm__ __volatile__(
  166.     "movb %%al,%%ah\n"
  167.     "1:\tmovb (%1),%%al\n\t"
  168.     "cmpb %%ah,%%al\n\t"
  169.     "je 2f\n\t"
  170.     "incl %1\n\t"
  171.     "testb %%al,%%al\n\t"
  172.     "jne 1b\n\t"
  173.     "xorl %1,%1\n"
  174.     "2:\tmovl %1,%0\n\t"
  175.     :"=a" (__res), "=r" (s)
  176.     :"0" (c),      "1"  (s));
  177. return __res;
  178. }
  179.  
  180. #define __HAVE_ARCH_STRRCHR
  181. extern inline char * strrchr(const char * s, int c)
  182. {
  183. register char * __res;
  184. __asm__ __volatile__(
  185.     "cld\n\t"
  186.     "movb %%al,%%ah\n"
  187.     "1:\tlodsb\n\t"
  188.     "cmpb %%ah,%%al\n\t"
  189.     "jne 2f\n\t"
  190.     "leal -1(%%esi),%0\n"
  191.     "2:\ttestb %%al,%%al\n\t"
  192.     "jne 1b"
  193.     :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
  194. return __res;
  195. }
  196.  
  197. #define __HAVE_ARCH_STRSPN
  198. extern inline size_t strspn(const char * cs, const char * ct)
  199. {
  200. register char * __res;
  201. __asm__ __volatile__(
  202.     "cld\n\t"
  203.     "movl %4,%%edi\n\t"
  204.     "repne\n\t"
  205.     "scasb\n\t"
  206.     "notl %%ecx\n\t"
  207.     "decl %%ecx\n\t"
  208.     "movl %%ecx,%%edx\n"
  209.     "1:\tlodsb\n\t"
  210.     "testb %%al,%%al\n\t"
  211.     "je 2f\n\t"
  212.     "movl %4,%%edi\n\t"
  213.     "movl %%edx,%%ecx\n\t"
  214.     "repne\n\t"
  215.     "scasb\n\t"
  216.     "je 1b\n"
  217.     "2:\tdecl %0"
  218.     :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
  219.     :"ax","cx","dx","di");
  220. return __res-cs;
  221. }
  222.  
  223. #define __HAVE_ARCH_STRCSPN
  224. extern inline size_t strcspn(const char * cs, const char * ct)
  225. {
  226. register char * __res;
  227. __asm__ __volatile__(
  228.     "cld\n\t"
  229.     "movl %4,%%edi\n\t"
  230.     "repne\n\t"
  231.     "scasb\n\t"
  232.     "notl %%ecx\n\t"
  233.     "decl %%ecx\n\t"
  234.     "movl %%ecx,%%edx\n"
  235.     "1:\tlodsb\n\t"
  236.     "testb %%al,%%al\n\t"
  237.     "je 2f\n\t"
  238.     "movl %4,%%edi\n\t"
  239.     "movl %%edx,%%ecx\n\t"
  240.     "repne\n\t"
  241.     "scasb\n\t"
  242.     "jne 1b\n"
  243.     "2:\tdecl %0"
  244.     :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
  245.     :"ax","cx","dx","di");
  246. return __res-cs;
  247. }
  248.  
  249. #define __HAVE_ARCH_STRPBRK
  250. extern inline char * strpbrk(const char * cs,const char * ct)
  251. {
  252. register char * __res;
  253. __asm__ __volatile__(
  254.     "cld\n\t"
  255.     "movl %4,%%edi\n\t"
  256.     "repne\n\t"
  257.     "scasb\n\t"
  258.     "notl %%ecx\n\t"
  259.     "decl %%ecx\n\t"
  260.     "movl %%ecx,%%edx\n"
  261.     "1:\tlodsb\n\t"
  262.     "testb %%al,%%al\n\t"
  263.     "je 2f\n\t"
  264.     "movl %4,%%edi\n\t"
  265.     "movl %%edx,%%ecx\n\t"
  266.     "repne\n\t"
  267.     "scasb\n\t"
  268.     "jne 1b\n\t"
  269.     "decl %0\n\t"
  270.     "jmp 3f\n"
  271.     "2:\txorl %0,%0\n"
  272.     "3:"
  273.     :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
  274.     :"ax","cx","dx","di");
  275. return __res;
  276. }
  277.  
  278. #define __HAVE_ARCH_STRSTR
  279. extern inline char * strstr(const char * cs,const char * ct)
  280. {
  281. register char * __res;
  282. __asm__ __volatile__(
  283.     "cld\n\t" \
  284.     "movl %4,%%edi\n\t"
  285.     "repne\n\t"
  286.     "scasb\n\t"
  287.     "notl %%ecx\n\t"
  288.     "decl %%ecx\n\t"    /* NOTE! This also sets Z if searchstring='' */
  289.     "movl %%ecx,%%edx\n"
  290.     "1:\tmovl %4,%%edi\n\t"
  291.     "movl %%esi,%%eax\n\t"
  292.     "movl %%edx,%%ecx\n\t"
  293.     "repe\n\t"
  294.     "cmpsb\n\t"
  295.     "je 2f\n\t"        /* also works for empty string, see above */
  296.     "xchgl %%eax,%%esi\n\t"
  297.     "incl %%esi\n\t"
  298.     "cmpb $0,-1(%%eax)\n\t"
  299.     "jne 1b\n\t"
  300.     "xorl %%eax,%%eax\n\t"
  301.     "2:"
  302.     :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
  303.     :"cx","dx","di","si");
  304. return __res;
  305. }
  306.  
  307. #define __HAVE_ARCH_STRLEN
  308. extern inline size_t strlen(const char * s)
  309. {
  310. /*
  311.  * slightly slower on a 486, but with better chances of
  312.  * register allocation
  313.  */
  314. register char dummy, *tmp= (char *)s;
  315. __asm__ __volatile__(
  316.     "\n1:\t"
  317.     "movb\t(%0),%1\n\t"
  318.     "incl\t%0\n\t"
  319.     "testb\t%1,%1\n\t"
  320.     "jne\t1b"
  321.     :"=r" (tmp),"=q" (dummy)
  322.     :"0" (s)
  323.     : "memory" );
  324. return (tmp-s-1);
  325. }
  326.  
  327. /* Added by Gertjan van Wingerde to make minix and sysv module work */
  328. #define __HAVE_ARCH_STRNLEN
  329. extern inline size_t strnlen(const char * s, size_t count)
  330. {
  331. register int __res;
  332. __asm__ __volatile__(
  333.     "movl %1,%0\n\t"
  334.     "jmp 2f\n"
  335.     "1:\tcmpb $0,(%0)\n\t"
  336.     "je 3f\n\t"
  337.     "incl %0\n"
  338.     "2:\tdecl %2\n\t"
  339.     "cmpl $-1,%2\n\t"
  340.     "jne 1b\n"
  341.     "3:\tsubl %1,%0"
  342.     :"=a" (__res)
  343.     :"c" (s),"d" (count)
  344.     :"dx");
  345. return __res;
  346. }
  347. /* end of additional stuff */
  348.  
  349. #define __HAVE_ARCH_STRTOK
  350. extern inline char * strtok(char * s,const char * ct)
  351. {
  352. register char * __res;
  353. __asm__ __volatile__(
  354.     "testl %1,%1\n\t"
  355.     "jne 1f\n\t"
  356.     "testl %0,%0\n\t"
  357.     "je 8f\n\t"
  358.     "movl %0,%1\n"
  359.     "1:\txorl %0,%0\n\t"
  360.     "movl $-1,%%ecx\n\t"
  361.     "xorl %%eax,%%eax\n\t"
  362.     "cld\n\t"
  363.     "movl %4,%%edi\n\t"
  364.     "repne\n\t"
  365.     "scasb\n\t"
  366.     "notl %%ecx\n\t"
  367.     "decl %%ecx\n\t"
  368.     "je 7f\n\t"            /* empty delimiter-string */
  369.     "movl %%ecx,%%edx\n"
  370.     "2:\tlodsb\n\t"
  371.     "testb %%al,%%al\n\t"
  372.     "je 7f\n\t"
  373.     "movl %4,%%edi\n\t"
  374.     "movl %%edx,%%ecx\n\t"
  375.     "repne\n\t"
  376.     "scasb\n\t"
  377.     "je 2b\n\t"
  378.     "decl %1\n\t"
  379.     "cmpb $0,(%1)\n\t"
  380.     "je 7f\n\t"
  381.     "movl %1,%0\n"
  382.     "3:\tlodsb\n\t"
  383.     "testb %%al,%%al\n\t"
  384.     "je 5f\n\t"
  385.     "movl %4,%%edi\n\t"
  386.     "movl %%edx,%%ecx\n\t"
  387.     "repne\n\t"
  388.     "scasb\n\t"
  389.     "jne 3b\n\t"
  390.     "decl %1\n\t"
  391.     "cmpb $0,(%1)\n\t"
  392.     "je 5f\n\t"
  393.     "movb $0,(%1)\n\t"
  394.     "incl %1\n\t"
  395.     "jmp 6f\n"
  396.     "5:\txorl %1,%1\n"
  397.     "6:\tcmpb $0,(%0)\n\t"
  398.     "jne 7f\n\t"
  399.     "xorl %0,%0\n"
  400.     "7:\ttestl %0,%0\n\t"
  401.     "jne 8f\n\t"
  402.     "movl %0,%1\n"
  403.     "8:"
  404.     :"=b" (__res),"=S" (___strtok)
  405.     :"0" (___strtok),"1" (s),"g" (ct)
  406.     :"ax","cx","dx","di","memory");
  407. return __res;
  408. }
  409.  
  410. #define __memcpy_c(d,s,count) \
  411. ((count%4==0) ? \
  412.  __memcpy_by4((d),(s),(count)) : \
  413.  ((count%2==0) ? \
  414.   __memcpy_by2((d),(s),(count)) : \
  415.   __memcpy_g((d),(s),(count))))
  416.  
  417. #define __HAVE_ARCH_MEMCPY
  418. #define memcpy(d,s,count) \
  419. (__builtin_constant_p(count) ? \
  420.  __memcpy_c((d),(s),(count)) : \
  421.  __memcpy_g((d),(s),(count)))
  422.  
  423. /*
  424.  *    These ought to get tweaked to do some cache priming.
  425.  */
  426.  
  427. extern inline void * __memcpy_by4(void * to, const void * from, size_t n)
  428. {
  429. register void *tmp = (void *)to;
  430. register int dummy1,dummy2;
  431. __asm__ __volatile__ (
  432.     "\n1:\tmovl (%2),%0\n\t"
  433.     "addl $4,%2\n\t"
  434.     "movl %0,(%1)\n\t"
  435.     "addl $4,%1\n\t"
  436.     "decl %3\n\t"
  437.     "jnz 1b"
  438.     :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2) 
  439.     :"1" (tmp), "2" (from), "3" (n/4)
  440.     :"memory");
  441. return (to);
  442. }
  443.  
  444. extern inline void * __memcpy_by2(void * to, const void * from, size_t n)
  445. {
  446. register void *tmp = (void *)to;
  447. register int dummy1,dummy2;
  448. __asm__ __volatile__ (
  449.     "shrl $1,%3\n\t"
  450.     "jz 2f\n"                 /* only a word */
  451.     "1:\tmovl (%2),%0\n\t"
  452.     "addl $4,%2\n\t"
  453.     "movl %0,(%1)\n\t"
  454.     "addl $4,%1\n\t"
  455.     "decl %3\n\t"
  456.     "jnz 1b\n"
  457.     "2:\tmovw (%2),%w0\n\t"
  458.     "movw %w0,(%1)"
  459.     :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2) 
  460.     :"1" (tmp), "2" (from), "3" (n/2)
  461.     :"memory");
  462. return (to);
  463. }
  464.  
  465. extern inline void * __memcpy_g(void * to, const void * from, size_t n)
  466. {
  467. register void *tmp = (void *)to;
  468. __asm__ __volatile__ (
  469.     "cld\n\t"
  470.     "shrl $1,%%ecx\n\t"
  471.     "jnc 1f\n\t"
  472.     "movsb\n"
  473.     "1:\tshrl $1,%%ecx\n\t"
  474.     "jnc 2f\n\t"
  475.     "movsw\n"
  476.     "2:\trep\n\t"
  477.     "movsl"
  478.     : /* no output */
  479.     :"c" (n),"D" ((long) tmp),"S" ((long) from)
  480.     :"cx","di","si","memory");
  481. return (to);
  482. }
  483.  
  484.  
  485. #define __HAVE_ARCH_MEMMOVE
  486. extern inline void * memmove(void * dest,const void * src, size_t n)
  487. {
  488. register void *tmp = (void *)dest;
  489. if (dest<src)
  490. __asm__ __volatile__ (
  491.     "cld\n\t"
  492.     "rep\n\t"
  493.     "movsb"
  494.     : /* no output */
  495.     :"c" (n),"S" (src),"D" (tmp)
  496.     :"cx","si","di");
  497. else
  498. __asm__ __volatile__ (
  499.     "std\n\t"
  500.     "rep\n\t"
  501.     "movsb\n\t"
  502.     "cld"
  503.     : /* no output */
  504.     :"c" (n), "S" (n-1+(const char *)src), "D" (n-1+(char *)tmp)
  505.     :"cx","si","di","memory");
  506. return dest;
  507. }
  508.  
  509. extern inline int memcmp(const void * cs,const void * ct,size_t count)
  510. {
  511. register int __res;
  512. __asm__ __volatile__(
  513.     "cld\n\t"
  514.     "repe\n\t"
  515.     "cmpsb\n\t"
  516.     "je 1f\n\t"
  517.     "sbbl %0,%0\n\t"
  518.     "orb $1,%b0\n"
  519.     "1:"
  520.     :"=abd" (__res):"0" (0),"S" (cs),"D" (ct),"c" (count)
  521.     :"si","di","cx");
  522. return __res;
  523. }
  524.  
  525. #define __HAVE_ARCH_MEMCHR
  526. extern inline void * memchr(const void * cs,int c,size_t count)
  527. {
  528. register void * __res;
  529. if (!count)
  530.     return NULL;
  531. __asm__ __volatile__(
  532.     "cld\n\t"
  533.     "repne\n\t"
  534.     "scasb\n\t"
  535.     "je 1f\n\t"
  536.     "movl $1,%0\n"
  537.     "1:\tdecl %0"
  538.     :"=D" (__res):"a" (c),"D" (cs),"c" (count)
  539.     :"cx");
  540. return __res;
  541. }
  542.  
  543. #define __memset_cc(s,c,count) \
  544. ((count%4==0) ? \
  545.  __memset_cc_by4((s),(c),(count)) : \
  546.  ((count%2==0) ? \
  547.   __memset_cc_by2((s),(c),(count)) : \
  548.   __memset_cg((s),(c),(count))))
  549.  
  550. #define __memset_gc(s,c,count) \
  551. ((count%4==0) ? \
  552.  __memset_gc_by4((s),(c),(count)) : \
  553.  ((count%2==0) ? \
  554.   __memset_gc_by2((s),(c),(count)) : \
  555.   __memset_gg((s),(c),(count))))
  556.  
  557. #define __HAVE_ARCH_MEMSET
  558. #define memset(s,c,count) \
  559. (__builtin_constant_p(c) ? \
  560.  (__builtin_constant_p(count) ? \
  561.   __memset_cc((s),(c),(count)) : \
  562.   __memset_cg((s),(c),(count))) : \
  563.  (__builtin_constant_p(count) ? \
  564.   __memset_gc((s),(c),(count)) : \
  565.   __memset_gg((s),(c),(count))))
  566.  
  567. extern inline void * __memset_cc_by4(void * s, char c, size_t count)
  568. {
  569. /*
  570.  * register char *tmp = s;
  571.  */
  572. register char *tmp = (char *)s;
  573. register int  dummy;
  574. __asm__ __volatile__ (
  575.     "\n1:\tmovl %2,(%0)\n\t"
  576.     "addl $4,%0\n\t"
  577.     "decl %1\n\t"
  578.     "jnz 1b"
  579.     :"=r" (tmp), "=r" (dummy)
  580.     :"q" (0x01010101UL * (unsigned char) c), "0" (tmp), "1" (count/4)
  581.     :"memory");
  582. return s;
  583. }
  584.  
  585. extern inline void * __memset_cc_by2(void * s, char c, size_t count)
  586. {
  587. register void *tmp = (void *)s;
  588. register int  dummy;
  589. __asm__ __volatile__ (
  590.     "shrl $1,%1\n\t"          /* may be divisible also by 4 */
  591.     "jz 2f\n"
  592.     "\n1:\tmovl %2,(%0)\n\t"
  593.     "addl $4,%0\n\t"
  594.     "decl %1\n\t"
  595.     "jnz 1b\n"
  596.     "2:\tmovw %w2,(%0)"
  597.     :"=r" (tmp), "=r" (dummy)
  598.     :"q" (0x01010101UL * (unsigned char) c), "0" (tmp), "1" (count/2)
  599.     :"memory");
  600. return s;
  601. }
  602.  
  603. extern inline void * __memset_gc_by4(void * s, char c, size_t count)
  604. {
  605. register void *tmp = (void *)s;
  606. register int dummy;
  607. __asm__ __volatile__ (
  608.     "movb %b0,%h0\n"
  609.     "pushw %w0\n\t"
  610.     "shll $16,%0\n\t"
  611.     "popw %w0\n"
  612.     "1:\tmovl %0,(%1)\n\t"
  613.     "addl $4,%1\n\t"
  614.     "decl %2\n\t"
  615.     "jnz 1b\n"
  616.     :"=q" (c), "=r" (tmp), "=r" (dummy)
  617.     :"0" ((unsigned) c),  "1"  (tmp), "2" (count/4)
  618.     :"memory");
  619. return s;
  620. }
  621.  
  622. extern inline void * __memset_gc_by2(void * s, char c, size_t count)
  623. {
  624. register void *tmp = (void *)s;
  625. register int dummy1,dummy2;
  626. __asm__ __volatile__ (
  627.     "movb %b0,%h0\n\t"
  628.     "shrl $1,%2\n\t"          /* may be divisible also by 4 */
  629.     "jz 2f\n\t"
  630.     "pushw %w0\n\t"
  631.     "shll $16,%0\n\t"
  632.     "popw %w0\n"
  633.     "1:\tmovl %0,(%1)\n\t"
  634.     "addl $4,%1\n\t"
  635.     "decl %2\n\t"
  636.     "jnz 1b\n"
  637.     "2:\tmovw %w0,(%1)"
  638.     :"=q" (dummy1), "=r" (tmp), "=r" (dummy2)
  639.     :"0" ((unsigned) c),  "1"  (tmp), "2" (count/2)
  640.     :"memory");
  641. return s;
  642. }
  643.  
  644. extern inline void * __memset_cg(void * s, char c, size_t count)
  645. {
  646. register void *tmp = (void *)s;
  647. __asm__ __volatile__ (
  648.     "shrl $1,%%ecx\n\t"
  649.     "rep\n\t"
  650.     "stosw\n\t"
  651.     "jnc 1f\n\t"
  652.     "movb %%al,(%%edi)\n"
  653.     "1:"
  654.     : /* no output */
  655.     :"c" (count),"D" (tmp), "a" (0x0101U * (unsigned char) c)
  656.     :"cx","di","memory");
  657. return s;
  658. }
  659.  
  660. extern inline void * __memset_gg(void * s,char c,size_t count)
  661. {
  662. register void *tmp = (void *)s;
  663. __asm__ __volatile__ (
  664.     "movb %%al,%%ah\n\t"
  665.     "shrl $1,%%ecx\n\t"
  666.     "rep\n\t"
  667.     "stosw\n\t"
  668.     "jnc 1f\n\t"
  669.     "movb %%al,(%%edi)\n"
  670.     "1:"
  671.     : /* no output */
  672.     :"c" (count),"D" (tmp), "a" (c)
  673.     :"cx","di","memory");
  674. return s;
  675. }
  676.  
  677.  
  678. /*
  679.  * find the first occurrence of byte 'c', or 1 past the area if none
  680.  */
  681. #define __HAVE_ARCH_MEMSCAN
  682. extern inline void * memscan(void * addr, int c, size_t size)
  683. {
  684.     if (!size)
  685.         return addr;
  686.     __asm__("cld
  687.         repnz; scasb
  688.         jnz 1f
  689.         dec %%edi
  690. 1:        "
  691.         : "=D" (addr), "=c" (size)
  692.         : "0" (addr), "1" (size), "a" (c));
  693.     return addr;
  694. }
  695.  
  696. #endif
  697.